package nmrworkflow.framework.executionmodule;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Copies data from the input stream to the output stream in 512-byte
 * chunks.  Runs an infinite loop that terminates when the input stream
 * is closed.  Blocks on reads so should be run in it's own thread.
 * 
 * @author rjn
 *
 */
public class StreamAdapter implements Runnable {
	InputStream inputStream;
	OutputStream outputStream;
	byte[] buffer = new byte[512]; // determined by default size of BufferedOutputStream
	
	public StreamAdapter(InputStream in, OutputStream out)
	{
		this.inputStream = new BufferedInputStream(in);
		this.outputStream = new BufferedOutputStream(out);
	}
	
	public StreamAdapter(InputStream in, File out) throws FileNotFoundException
	{
		this.inputStream = new BufferedInputStream(in);
		this.outputStream = new BufferedOutputStream(new FileOutputStream(out));
	}
	
	public StreamAdapter(File in, OutputStream out) throws FileNotFoundException
	{
		this.inputStream = new BufferedInputStream(new FileInputStream(in));
		this.outputStream = new BufferedOutputStream(out);
	}
	
	public StreamAdapter(File in, File out) throws FileNotFoundException
	{
		this.inputStream = new BufferedInputStream(new FileInputStream(in));
		this.outputStream = new BufferedOutputStream(new FileOutputStream(out));
	}
	
	/**
	 * Transfers a block of data from one process to another.
	 * @return
	 * @throws IOException
	 */
	protected int transfer() throws IOException
	{		
		int bytesRead;

		bytesRead = inputStream.read(buffer);
		if(bytesRead > 0) {
			outputStream.write(buffer, 0, bytesRead);
			outputStream.flush();
		}
		
		return bytesRead;
	}
	
	/**
	 * Starts loop that transfers data.
	 * @throws IOException
	 */
	public void run()
	{
		try {
			while(transfer() != -1)
				;
			inputStream.close();
			outputStream.close();
		} catch(IOException e) {
			e.printStackTrace();
		}
			
	}
	
}
